/**
 * 数组转化为树形结构
 * @param list 带转换数组
 * @param id id
 * @param pid 关联id
 * @returns {*[]}
 */
const convertListToTree = (list, id = 'id', pid = 'pid') => {
    const trees = []
    if (!Array.isArray(list)) {
        throw new Error('list必须为数组')
    }
    // 缓存所有的id与值
    const idMap = new Map()
    list.forEach(item => {
        idMap.set(item[id], item)
        if (!idMap.has(item[pid])) {
            trees.push(item)
        } else {
            findChild(trees, item[pid], item, id)
        }
    })
    return trees
}
const findChild = (list, pid, data, id = 'id') => {
    list.forEach(item => {
        item.children = (!item.children ? [] : item.children)
        if (item[id] === pid) {
            item.children.push(data)
        } else {
            if (Array.isArray(item.children.length)) {
                findChild(item.children, pid, data)
            }
        }
    })
}
/**
 * list集合排序、tree结构排序
 * @param list 待处理集合
 * @param sortName 排序字段
 * @param children 递归子元素
 * @param desc 降序
 * @returns {*}
 */
const sort = (list, sortName = 'sort', children = 'children', desc = true) => {
    if (!Array.isArray(list)) {
        throw new Error('list必须为数组')
    }
    const tempList = list.concat([])
    sortChildren(tempList, sortName, children, desc)
    return tempList
}
const sortChildren = (list, sortName = 'sort', children = 'children', desc = true) => {
    list.sort((item1, item2) => {
        return desc ? item1[sortName] - item2[sortName] : item2[sortName] - item1[sortName]
    })
    list.forEach(item => {
        if (Array.isArray(item[children])) {
            sortChildren(item.children, sortName, children)
        }
    })
}
/**
 * 递归查找节点路径
 * @param tree 待处理集合
 * @param path 路径地址（匹配的节点构成的递归数据）
 * @param callBack 回调函数（主动调用，工具传递当前节点），客户端返回true代表找到节点。
 * @returns {*[]|*}
 */
const findPath = (tree = [], path = [], callBack) => {
    if (!Array.isArray(tree)) {
        tree = [];
    }
    if (!Array.isArray(path)) {
        path = [];
    }
    for (let i = 0; i < tree.length; i++) {
        const tempPath = [...path];
        tempPath.push(tree[i])
        if (callBack && callBack(tree[i])) {
            return tempPath
        }
        if (tree[i].children) {
            const result = findPath(tree[i].children, tempPath, callBack)
            if (result) {
                return result
            }
        }
    }
}
module.exports = {
    convertListToTree,
    sort,
    findPath
}